﻿using System;

namespace DataCenter.Share
{
    [Serializable]
	public unsafe class DayBinary : Binary
	{
        public DayBinary() : this(1, 1) { }
        public DayBinary(int interval, int fieldCount)
        {
            this.Initialize(interval, fieldCount);
        }
        public DayBinary(byte[] buffer)
        {
            this.Initialize(buffer);
        }
        public DayBinary(TimeLine line)
        {
            Initialize(1, line.FieldCount);
            SetValue(line);
        }

        public override byte[] GetBuffer()
        {
            fixed (byte* pBuffer = buffer)
            {
                *((int*)(pBuffer + sizeof(byte))) = recordCount;
            }
            return buffer;
        }
        public override int GetRecordIndex(DateTime valueTime)
        {
            int timeIndex = GetTimeIndex(valueTime);
            return HeaderBufferLength + SingleBufferLength * timeIndex;
        }
        public override int GetRecordIndex(int timeIndex)
        {
            return HeaderBufferLength + SingleBufferLength * timeIndex;
        }

        protected override byte[] CreateBuffer()
		{
			byte[] buffer = new byte[TotalBufferLength];
			fixed (byte* pBuffer = buffer)
			{
				*(pBuffer) = Version;
				*((int*)(pBuffer + sizeof(byte))) = recordCount;
				*((int*)(pBuffer + sizeof(byte) + sizeof(int))) = interval;
				*((int*)(pBuffer + sizeof(byte) + sizeof(int) * 2)) = fieldCount;

                for (int i = HeaderBufferLength; i < TotalBufferLength; i++)
				{
					*(pBuffer + i) = EMPTY_FLAG;
				}
			}
			return buffer;
		}
        protected override int GetRecordCount()
        {
            return BitConverter.ToInt32(buffer, sizeof(byte));
        }
        protected override DateTime GetTimeFromRecordIndex(int recordIndex)
        {
            int timeIndex = (recordIndex - HeaderBufferLength) / SingleBufferLength;
            return GetTimeFromTimeIndex(timeIndex);
        }

        private void Initialize(int interval, int fieldCount)
        {
            SetParameters(interval, fieldCount);
            buffer = CreateBuffer();
        }
        private void Initialize(byte[] buffer)
        {            
            int interval = BitConverter.ToInt32(buffer, sizeof(byte) + sizeof(int));
            int fieldCount = BitConverter.ToInt32(buffer, sizeof(byte) + sizeof(int) * 2);
            SetParameters(interval, fieldCount);
            CheckBuffer(buffer);
            this.buffer = buffer;
            base.recordCount = GetRecordCount();
        }
        private void SetParameters(int interval, int fieldCount)
        {
            ThrowCheck(interval, fieldCount);
            base.Version = VERSION;
            base.interval = interval;
            base.fieldCount = fieldCount;
            base.TotalRecordCount = MINUTES_PER_DAY / interval;
            base.MAX_RECORD_COUNT = TotalRecordCount;
            base.HeaderBufferLength = HEADER_BUFFER_LENGTH;
            base.SingleBufferLength = sizeof(byte) + sizeof(float) * fieldCount;
            base.TotalBufferLength = HeaderBufferLength + SingleBufferLength * TotalRecordCount;
            base.StartTimeIndex = 0;
            base.EndTimeIndex = TotalRecordCount - 1;
        }
    }
}
